package ${package}.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package}.db.mapper.${ClassName}Mapper;
import ${package}.db.model.${ClassName};
<#if exportExcel>
import ${package}.dto.${classname}.excel.${ClassName}ExcelExportDto;
</#if>
<#if importExcel>
import ${package}.dto.${classname}.excel.${ClassName}ExcelImportDto;
</#if>
import ${package}.dto.${classname}.req.${ClassName}AddDto;
import ${package}.dto.${classname}.req.${ClassName}EditDto;
<#if importExcel>
import ${package}.dto.${classname}.req.${ClassName}ImportDto;
</#if>
import ${package}.dto.${classname}.req.${ClassName}ListDto;
import ${package}.dto.${classname}.res.${ClassName}DetailRes;
import ${package}.service.${ClassName}Service;
import ${package}.utils.OrikaUtils;
import com.imydao.support.system.res.BaseRes;
import com.imydao.support.system.system.enums.BasicNewEnum;
<#if exportExcel>
import com.imydao.support.tool.excel.ExcelUtils;
</#if>
<#if importExcel>
import com.imydao.support.tool.excel.res.ExcelRes;
</#if>
import com.imydao.support.tool.page.res.PageBean;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
<#if importExcel>
import org.springframework.web.multipart.MultipartFile;
</#if>

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ${tableComment}
 *
 * @author ${author} ${email}
 * @since ${version} ${date}
 */
@Slf4j
@Service
@AllArgsConstructor
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements ${ClassName}Service {

    private final ${ClassName}Mapper ${className}Mapper;

    @Override
    public BaseRes<PageBean<${ClassName}>> pageList(${ClassName}ListDto dto) {
        if (StrUtil.isBlank(dto.getOrderBy())) {
            dto.setOrderBy("id desc");
        } else {
            //ORDER BY LENGTH(compactness) asc, compactness asc
            //驼峰转下划线
            String orderColumn = StrUtil.toUnderlineCase(dto.getOrderBy());
            if (StrUtil.isNotBlank(orderColumn)) {
                String[] orderWords = orderColumn.split(" ");
                if (orderWords.length == 2) {
                    String sortSql = "LENGTH(" + orderWords[0] + ") " + orderWords[1] + "," + orderColumn;
                    dto.setOrderBy(sortSql + ", id desc");
                } else {
                    dto.setOrderBy(StrUtil.toUnderlineCase(dto.getOrderBy()) + ", id desc");
                }
            }
        }
        dto.start();
        List<${ClassName}> list = ${className}Mapper.selectByWhere(dto);
        return BaseRes.getSuccess(PageBean.getPageBean(list));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseRes<Long> add(${ClassName}AddDto dto) {
        //1、构造实体对象
        ${ClassName} entity = OrikaUtils.convert(dto, ${ClassName}.class);
        //2、对象入库
        boolean saveResult = this.save(entity);
        log.info("保存${tableComment}返回：{}", saveResult);
        return BaseRes.getSuccess(entity.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseRes<Long> edit(${ClassName}EditDto dto) {
        //1、查询实体对象
        ${ClassName} entity = this.getById(dto.getId());
        if (entity == null) {
            return BaseRes.getError("object.not.exist");
        }
        //2、更新实体对象，忽略null值
        BeanUtil.copyProperties(dto, entity, CopyOptions.create().setIgnoreNullValue(true));
        //3、对象更新入库
        boolean updateResult = this.updateById(entity);
        log.info("更新${tableComment}返回：{}", updateResult);
        return BaseRes.getSuccess(entity.getId());
    }

<#if importExcel>
    @SneakyThrows(Exception.class)
    @Override
    public BaseRes<ExcelRes<${ClassName}ExcelImportDto>> importExcel(MultipartFile excel, ${ClassName}ImportDto dto) {
        //1、解析excel数据（如获取数据为空，请检查titleRows和headerRows配置是否正确）
        List<${ClassName}ExcelImportDto> importDataList = ExcelUtils
                .importExcel(excel, 1, 1, 0, ${ClassName}ExcelImportDto.class);
        if (importDataList == null || importDataList.isEmpty()) {
            log.error("excel无内容");
            return BaseRes.getI18nError("basic.excel.no.content");
        }
        //2、过滤空行（指定字段为空或空白行）
        importDataList = importDataList.stream().filter(x -> !x.isEmpty()).collect(Collectors.toList());
        if (importDataList.isEmpty()) {
            log.error("excel校验为空白行，无正确内容");
            return BaseRes.getI18nError("basic.excel.no.content");
        }
        //3、数据校验
        String errMsg = validExcelData(importDataList);
        if (errMsg != null) {
            return BaseRes.getI18nError(errMsg);
        }
        //4、批量入库
        List<${ClassName}> persistentDateList = importDataList.stream()
                .map(x -> OrikaUtils.convert(x, ${ClassName}.class))
                .collect(Collectors.toList());
        boolean saveBatchResult = this.saveBatch(persistentDateList, 500);
        log.info("批量入库${tableComment}返回：{}", saveBatchResult);
        //5、返回导入结果信息
        ExcelRes<${ClassName}ExcelImportDto> importResult = new ExcelRes<>();
        importResult.setTotal(importDataList.size());
        importResult.setInsertTotal(persistentDateList.size());
        importResult.setFailTotal(0);
        return BaseRes.getSuccess(importResult);
    }
</#if>

<#if exportExcel>
    @Override
    public List<${ClassName}ExcelExportDto> exportExcel(${ClassName}ListDto dto) {
        List<${ClassName}ExcelExportDto> resultList = Collections.emptyList();
        //分页响应数据
        BaseRes<PageBean<${ClassName}>> pageList = this.pageList(dto);
        if (pageList.success()) {
            //分页数据
            PageBean<${ClassName}> listData = pageList.getData();
            //列表数据
            List<${ClassName}> list = listData.getList();
            //对象转换
            resultList = list.stream()
                            .map(x -> OrikaUtils.convert(x, ${ClassName}ExcelExportDto.class))
                            .collect(Collectors.toList());
        }
        return resultList;
    }
</#if>

    @Override
    public BaseRes<${ClassName}DetailRes> detail(Long id) {
        //1、查询实体对象
        ${ClassName} ${className} = this.getById(id);
        if (${className} == null) {
            return BaseRes.getError("object.not.exist");
        }
        //2、构造返回对象
        return BaseRes.getSuccess(OrikaUtils.convert(${className}, ${ClassName}DetailRes.class));
    }

    @Override
    public BaseRes<Long> delete(Long id) {
        //1、查询实体对象
        ${ClassName} entity = this.getById(id);
        if (entity == null) {
            return BaseRes.getError("object.not.exist");
        }
        //2、更新逻辑删除
        entity.setDeleted(BasicNewEnum.NO.getCode().byteValue());
        //entity.setDeleteTime(LocalDateTime.now());
        this.updateById(entity);
        return BaseRes.getSuccess(id);
    }

<#if importExcel>
    /**
     * excel 导入数据校验
     * @param importDataList 待导入数据
     * @return null标识校验通过，反之不通过，提示国际化信息
     */
    private String validExcelData(List<${ClassName}ExcelImportDto> importDataList) {
        //返回文字需要国际化！
        return null;
    }
</#if>
}